package com.elbis.business.controller.auth;

import java.util.GregorianCalendar;
import java.util.List;
import java.util.TimeZone;

import javax.faces.event.ComponentSystemEvent;

import org.apache.log4j.Logger;

import com.elbis.access.wg.api.response.WOTError;
import com.elbis.access.wg.api.response.auth.OpenIDLoginResponse;
import com.elbis.action.input.ErrorMessages;
import com.elbis.action.input.ErrorsHashMap;
import com.elbis.business.GameTypes;
import com.elbis.business.controller.LanguageController;
import com.elbis.business.controller.LoginController;
import com.elbis.business.controller.msg.FormFields;
import com.elbis.business.entity.Game;
import com.elbis.business.entity.Gamer;
import com.elbis.business.entity.authentication.Authentication;
import com.elbis.business.manager.AuthenticationManager;
import com.elbis.business.manager.GameManager;
import com.elbis.business.manager.ManageGamer;
import com.elbis.business.manager.MessageManager;
import com.elbis.business.model.ReturnTypes;
import com.elbis.business.util.ErrorMessageUtil;

public class WOTAuthenticationResponseController {

	private static final Logger logger = Logger
			.getLogger(WOTAuthenticationResponseController.class);

	private String status = null;

	private String accessToken = null;

	private String expiresAt = null;

	private String accountId = null;

	private String nickname = null;

	private String code = null;

	private String message = null;

	private LoginController loginBean = null;

	private LanguageController languageBean = null;

	private OpenIDLoginResponse response = null;

	public void process(ComponentSystemEvent event) {

		WOTError wotError = null;
		response = new OpenIDLoginResponse();

		if (status == null) {
			wotError = new WOTError();
			wotError.setCode("-1");
			wotError.setMessage("Invalid status code");
			response.setError(wotError);
			ErrorMessageUtil.addErrorMessage(
					FormFields.AUTHENTICATION_RESPONSE, response.toString());
			return;
		}

		response.setStatus(status);

		if (!ReturnTypes.STATUS_OK.equalsIgnoreCase(status)) {
			wotError = new WOTError();
			wotError.setCode(code);
			wotError.setMessage(message);
			response.setError(wotError);
			logger.warn(ErrorsHashMap.getMessage(ErrorMessages.WOT_API_ERROR));
			ErrorMessageUtil.addErrorMessage(
					FormFields.AUTHENTICATION_RESPONSE,
					MessageManager.getErrorMessage(ErrorMessages.WOT_API_ERROR,
							languageBean.getLocaleCode()).getMessage());
		} else {
			Gamer gamer = loginBean.getCurrentGamer();
			if (gamer != null) {

				if (accessToken == null || accountId == null
						|| nickname == null || expiresAt == null) {
					logger.warn(ErrorsHashMap
							.getMessage(ErrorMessages.WOT_API_ERROR)
							+ " invalid authentication values in response");
					ErrorMessageUtil.addErrorMessage(
							FormFields.AUTHENTICATION_RESPONSE,
							MessageManager.getErrorMessage(
									ErrorMessages.WOT_API_ERROR,
									languageBean.getLocaleCode()).getMessage());
					return;
				}

				response.setAccess_token(accessToken);
				response.setAccount_id(Long.valueOf(accountId));
				response.setNickname(nickname);
				GregorianCalendar expirationDate = new GregorianCalendar(
						TimeZone.getTimeZone("GMT"));
				expirationDate.setTimeInMillis(expirationDate.getTimeInMillis()
						+ Long.parseLong(expiresAt));
				response.setExpires_at(expirationDate.getTime());

				ManageGamer mg = new ManageGamer();
				AuthenticationManager am = new AuthenticationManager();
				Game wot = gamer.getGame(GameTypes.WORLD_OF_TANKS);
				if (wot == null) {
					GameManager gm = new GameManager();
					wot = gm.getGame(GameTypes.WORLD_OF_TANKS);
					gamer.addGame(wot);
				}

				Authentication auth = new Authentication();
				auth.setGame(wot);
				auth.setGamer(gamer);
				auth.setExpires(expirationDate.getTime());
				auth.setToken(accessToken);
				List<Authentication> gamerAuthentications = gamer
						.getAuthentications();
				if (gamerAuthentications != null
						&& gamerAuthentications.contains(auth)) {
					Authentication existingAuth = gamerAuthentications
							.get(gamerAuthentications.indexOf(auth));
					existingAuth.setExpires(auth.getExpires());
					existingAuth.setToken(auth.getToken());
					am.update(existingAuth);
				} else {
					gamer.addAuthentication(auth);
					mg.update(gamer);
				}
				ErrorMessageUtil
						.addInformativeMessage(
								FormFields.AUTHENTICATION_RESPONSE,
								response.toString());
			} else {
				logger.warn(ErrorsHashMap
						.getMessage(ErrorMessages.USER_SESSION_ERROR));
				ErrorMessageUtil.addErrorMessage(
						FormFields.AUTHENTICATION_RESPONSE,
						MessageManager.getErrorMessage(
								ErrorMessages.SYSTEM_ERROR,
								languageBean.getLocaleCode()).getMessage());
			}
		}
	}

	public String getStatus() {
		return status;
	}

	public void setStatus(String status) {
		this.status = status;
	}

	public String getAccessToken() {
		return accessToken;
	}

	public void setAccessToken(String accessToken) {
		this.accessToken = accessToken;
	}

	public String getExpiresAt() {
		return expiresAt;
	}

	public void setExpiresAt(String expiresAt) {
		this.expiresAt = expiresAt;
	}

	public String getAccountId() {
		return accountId;
	}

	public void setAccountId(String accountId) {
		this.accountId = accountId;
	}

	public String getNickname() {
		return nickname;
	}

	public void setNickname(String nickname) {
		this.nickname = nickname;
	}

	public String getCode() {
		return code;
	}

	public void setCode(String code) {
		this.code = code;
	}

	public String getMessage() {
		return message;
	}

	public void setMessage(String message) {
		this.message = message;
	}

	public LoginController getLoginBean() {
		return loginBean;
	}

	public void setLoginBean(LoginController loginBean) {
		this.loginBean = loginBean;
	}

	public LanguageController getLanguageBean() {
		return languageBean;
	}

	public void setLanguageBean(LanguageController languageBean) {
		this.languageBean = languageBean;
	}

	public OpenIDLoginResponse getResponse() {
		return response;
	}

	public void setResponse(OpenIDLoginResponse response) {
		this.response = response;
	}

}